package com.xs.shop.user.service.utils;

import com.xs.shop.common.exceptions.enums.Resp;
import com.xs.shop.user.service.config.JwtConfig;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.SignatureException;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.UUID;

/**
 * @author xs
 */
@Component
public class JwtUtil {

    @Resource
    private JwtConfig jwtConfig;

    private String generateToken(Claims claims, Long ttl, String key){
        return Jwts.builder()
                .setClaims(claims)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + ttl))
                .signWith(Keys.hmacShaKeyFor(key.getBytes(StandardCharsets.UTF_8)))
                .compact();
    }

    public String generateAccessToken(Claims claims){
        return this.generateToken(claims, jwtConfig.getAccessTokenTtl(), jwtConfig.getAccessTokenKey());
    }

    public String generateRefreshToken(Claims claims){
        return this.generateToken(claims, jwtConfig.getRefreshTokenTtl(), jwtConfig.getRefreshTokenKey());
    }

    private Claims parseToken(String token, String key){
        return Jwts.parserBuilder()
                .setSigningKey(Keys.hmacShaKeyFor(key.getBytes(StandardCharsets.UTF_8)))
                .build()
                .parseClaimsJws(token)
                .getBody();
    }

    public Claims parseAccessToken(String token){
        return this.parseToken(token, jwtConfig.getAccessTokenKey());
    }

    public Claims parseRefreshToken(String token){
        return this.parseToken(token, jwtConfig.getRefreshTokenKey());
    }


    /**
     * 校验token
     * @param token token
     * @return 校验结果
     * Valid-合法
     * Expired-过期
     * Invalid-无效
     * Malformed-结构不符合标准
     * Invalid Signature-签名无效
     */
    private String validateToken(String token, String key) {
        try {
            Jwts.parserBuilder()
                    .setSigningKey(Keys.hmacShaKeyFor(key.getBytes(StandardCharsets.UTF_8)))
                    .build()
                    .parseClaimsJws(token);
            return "Valid";
        } catch (ExpiredJwtException e) {
            return "Expired";
        } catch (SignatureException e) {
            return "Invalid Signature";
        } catch (MalformedJwtException e) {
            return "Malformed";
        } catch (Exception e) {
            return "Invalid";
        }
    }

//    private Resp validateToken(String token, String key) {
//        try {
//            Jwts.parserBuilder()
//                    .setSigningKey(Keys.hmacShaKeyFor(key.getBytes(StandardCharsets.UTF_8)))
//                    .build()
//                    .parseClaimsJws(token);
//            return Resp.SUCCESS;
//        } catch (Exception e) {
//            return Resp.FAIL;
//        }
//    }

    public String validateAccessToken(String token){
        return this.validateToken(token, jwtConfig.getAccessTokenKey());
    }

    public String validateRefreshToken(String token){
        return this.validateToken(token, jwtConfig.getRefreshTokenKey());
    }

    public boolean isTokenExpired(String token, String key) {
        try {
            Claims claims = parseToken(token, key);
            Date expiration = claims.getExpiration();
            return expiration.before(new Date());
        } catch (Exception e) {
            return true;
        }
    }

    public boolean isAccessTokenExpired(String token){
        return this.isTokenExpired(token, jwtConfig.getAccessTokenKey());
    }

    public boolean isRefreshTokenExpired(String token){
        return this.isTokenExpired(token, jwtConfig.getRefreshTokenKey());
    }

    public String generateRefreshToken() {
        return UUID.randomUUID().toString();
    }
}